package com.lbh.platforms.windows;

import com.jogamp.openal.AL;
import com.lbh.audio.OpenAL;
import com.lbh.platforms.windows.structures.gdi.PIXELFORMATDESCRIPTOR;
import com.lbh.platforms.windows.structures.user.MSG;
import com.lbh.platforms.windows.structures.user.WNDCLASSA;
import com.sun.jna.Pointer;

import java.io.File;
import java.io.IOException;

import static com.lbh.platforms.windows.WinGdi32.*;
import static com.lbh.platforms.windows.WinUser32.ins;
import static com.lbh.platforms.windows.WinUser32.*;

/***
 * project:JRuntime
 * package:com.lbh.platforms.windows
 *
 * @author user:lenovo QQ:1601078366
 * @date 2021/10/21 1:19
 * @version V1.0
 */
public class WinStart {

    public static Pointer hWnd;
    private static Pointer hdc;
    private static Pointer hglrc;

    private static void EnableOpenGL(Pointer hwnd) {
        PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
        int iFormat;
        hWnd = hwnd;
        hdc = ins.GetDC(hWnd);
        pfd.nSize = PIXELFORMATDESCRIPTOR.SIZE;
        pfd.nVersion = 1;
        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 24;
        pfd.cDepthBits = 16;
        pfd.iLayerType = PFD_MAIN_PLANE;

        iFormat = WinGdi32.ins.ChoosePixelFormat(hdc, pfd);
        WinGdi32.ins.SetPixelFormat(hdc, iFormat, pfd);

        hglrc = WinOpenGL32.ins.wglCreateContext(hdc);
        WinOpenGL32.ins.wglMakeCurrent(hdc, hglrc);
    }

    private static void DisableOpenGL() {
        WinOpenGL32.ins.wglMakeCurrent(null, null);
        WinOpenGL32.ins.wglDeleteContext(hglrc);
        ins.ReleaseDC(hWnd, hdc);
    }

    public static void main() {
        try {
            WinKernel32.ins.SetCurrentDirectoryA(new File(".").getCanonicalPath() + "/target/classes");
        } catch (IOException e) {
            e.printStackTrace();
        }
        WNDCLASSA wc = new WNDCLASSA();
        Pointer hInstance = WinKernel32.ins.GetModuleHandleA(null);
        Pointer hWnd;
        MSG msg = new MSG();
        wc.style = CS_OWNDC;
        wc.lpfnWndProc = WinEvent.wndProc;
        wc.cbClsExtra = 0;
        wc.cbWndExtra = 0;
        wc.hInstance = hInstance;
        wc.hIcon = ins.LoadIconA(null, Pointer.createConstant(IDI_APPLICATION));
        wc.hCursor = ins.LoadCursorA(null, Pointer.createConstant(IDC_ARROW));
        wc.hbrBackground = WinGdi32.ins.GetStockObject(BLACK_BRUSH);
        wc.lpszMenuName = null;
        wc.lpszClassName = "GLSample";
        ins.RegisterClassA(wc);
        hWnd = ins.CreateWindowExA(
                0, "GLSample", "OpenGL Sample",
                WS_POPUPWINDOW | WS_VISIBLE | WS_CAPTION,
                0, 0, 512, 512,
                null, null, hInstance, null);
        ins.ShowCursor(true);
        WinEvent.keyDownEvents.add(key -> {
            if (key == VK_ESCAPE) {
                ins.PostQuitMessage(0);
            }
        });

        boolean quit = false;

        EnableOpenGL(hWnd);

        WinRender.init();

        OpenAL.loadAudioFiles(new String[]{"audio.wav"});
        OpenAL.audioPlay(0, AL.AL_TRUE);

        while (!quit) {
            if (ins.PeekMessageA(msg, null, 0, 0, PM_REMOVE)) {
                if (msg.message == WM_QUIT) {
                    quit = true;
                } else {
                    ins.TranslateMessage(msg);
                    ins.DispatchMessageA(msg);
                }
            } else {
                WinRender.render();
                WinGdi32.ins.SwapBuffers(hdc);
                WinKernel32.ins.Sleep(1);
            }
        }

        DisableOpenGL();

        OpenAL.uninitialize();

        ins.DestroyWindow(hWnd);
    }
}
